using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Alicanto.Helpers
{
    internal class Conversion
    {
        static internal void Equalize(ref Expression x, ref Expression y)
        {
            if (x.Type != typeof(object) && y.Type == typeof(object))
            {
                y = Expression.Convert(
                    y,
                    x.Type
                );
            }
            else if (y.Type != typeof(object) && x.Type == typeof(object))
            {
                x = Expression.Convert(
                    x,
                    y.Type
                );
            }
        }

        static internal IList<Expression> EnsureParameterTypes(IList<Expression> arguments, IList<Type> parameterTypes)
        {
            for (int i = 0; i < parameterTypes.Count; i++)
                arguments[i] = EnsureType(arguments[i], parameterTypes[i]);

            return arguments;
        }

        static Expression EnsureType(Expression x, Type type)
        {
            if (x.Type == type)
                return x;
            else
                return Expression.Convert(
                    x,
                    type
                );
                    
        }

        static internal void EqualizeNumbers(ref Expression x, ref Expression y)
        {
            if (x.Type != y.Type)
            {
                Type to = Typing.ResolveNumberConversion(x.Type, y.Type);
                if (x.Type != to)
                {
                    x = Expression.ConvertChecked(
                        x,
                        to
                    );
                }
                else
                {
                    y = Expression.ConvertChecked(
                        y,
                        to
                    );
                }
            }
        }

        static internal Expression Ensure(Expression x, Type type)
        {
            if (x.Type != type)
            {
                x = Expression.ConvertChecked(
                    x,
                    type
                );
            }

            return x;
        }

        static internal Expression EnsureString(Expression x)
        {
            if (x.Type != typeof(string))
            {
                x = Expression.Call(
                    x,
                    typeof(object).GetMethod("ToString")
                );
            }

            return x;
        }
    }
}
